/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.diagram.component.helper;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.uml2.uml.Artifact;
import org.eclipse.uml2.uml.Component;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.UMLFactory;

import com.cea.papyrus.core.helper.NodeHelper;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagram.component.Activator;
import com.cea.papyrus.diagram.component.preference.ComponentDiagramPreferenceConstants;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;

// TODO: Auto-generated Javadoc
/**
 * Defines management of artifacts.
 * 
 * @author A. Lanusse
 * @since 15 mai 2007
 */
public class NodeArtifactHelper extends NodeHelper {

	/**
	 * The channel.
	 */
	private int channel = 203;


    ///////////////////////////////////////////////////////////////////////////
    // UML Management
    ///////////////////////////////////////////////////////////////////////////
	
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.helper.NodeHelper#createUMLElement(java.lang.String, org.eclipse.uml2.uml.Element)
	 */

	@Override
	public  org.eclipse.uml2.uml.Element createUMLElement(String name, org.eclipse.uml2.uml.Element umlParent){
		Debug.debug(this,"createUMLElement(String,Element)", channel); 

		// create Artifact
		org.eclipse.uml2.uml.Artifact anArtifact = UMLFactory.eINSTANCE.createArtifact();
		anArtifact.setName(name);
		if (umlParent instanceof Artifact) {
			((Artifact) umlParent).getNestedArtifacts().add(anArtifact);			
		} else if (umlParent instanceof Component) {
			((Component) umlParent).getPackagedElements().add(anArtifact);
		} else if (umlParent instanceof Package) {
			((Package) umlParent).getPackagedElements().add(anArtifact);	
		}
		return anArtifact;		
	}
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.helper.NodeHelper#getNewUMLElementName(org.eclipse.uml2.uml.Element)
	 */
	@Override
	public String getNewUMLElementName(Element umlParent) {
		String name = ""; //$NON-NLS-1$
	
		// i <10000: avoid infinite loops
		for(int i=0; i< 10001; i++ ) {
			name = getBaseString()+i;
			
			if (umlParent instanceof Artifact){
				if(null == ((Artifact)umlParent).getNestedArtifact(name)) {
					return name;
				}
			}
			else if (umlParent instanceof Component){
				if(null == ((Component)umlParent).getPackagedElement(name)) {
					return name;
				}
			}
			else if (umlParent instanceof Package){
				if(null == ((Package)umlParent).getPackagedElement(name)) {
					return name;
				}
			}else {
				if(null == ((Package)umlParent.getNearestPackage()).getPackagedElement(name)) {
					return name;
				}
			}	
		}
		return getBaseString()+"X"; //$NON-NLS-1$
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#canExecuteCreateElement(org.eclipse.uml2.uml.Element)
	 */

	@Override
	public boolean canCreateUMLElement(Element umlParent) {
		if ( (umlParent instanceof Artifact) || (umlParent instanceof Component) || (umlParent instanceof Package) ) {
			return true;
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.helper.NodeHelper#addUMLElement(org.eclipse.uml2.uml.Element, org.eclipse.uml2.uml.Element)
	 */

	@Override
	public boolean addUMLElement(Element element, Element umlParent) {
		if (umlParent instanceof Artifact){
			return ((Artifact)umlParent).getNestedArtifacts().add((Artifact)element);		
		}
		else if (umlParent instanceof Component){
			return ((Component)umlParent).getPackagedElements().add((PackageableElement) element);		
		}
		else if (umlParent instanceof Package) {
			return ((Package)umlParent).getPackagedElements().add((PackageableElement)element);
		}
		return false;
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#removeElement(org.eclipse.uml2.uml.Element, org.eclipse.uml2.uml.Element)
	 */

	@Override
	public boolean removeUMLElement(Element element, Element umlParent) {
		if (umlParent instanceof Artifact){
			return ((Artifact)umlParent).getNestedArtifacts().remove(element);		
		}
		else if (umlParent instanceof Component){			
			((Component)umlParent).getPackagedElements().remove(element);			
		} 
		else if (umlParent instanceof Package) {				
			return ((Package)umlParent).getPackagedElements().remove(element);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#getBaseString()
	 */
	/**
	 * 
	 * 
	 * @return 
	 */
	@Override
	public String getBaseString() {
		return "Artifact_"; //$NON-NLS-1$
	}
	
	/**********************************************************************************
	 * 
	 * GRAPH MANAGEMENT
	 * 
	 **********************************************************************************
	 */
	
	
//	/* (non-Javadoc)
//	 * @see com.cea.papyrus.common.helper.NodeHelper#createGraphElement(org.eclipse.uml2.uml.Element, com.cea.papyrus.diagraminterchange2.di2.GraphElement, org.eclipse.draw2d.geometry.Point, org.eclipse.draw2d.geometry.Dimension)
//	 */
//	@Override
//	public GraphNode createGraphElement(Element umlChild, GraphElement parent, Point location, Dimension size){
//		Debug.debug(this,"Call NodeArtifactFactory.createGraphNode()", channel); //$NON-NLS-1$	 
//		GraphNode graphNode=super.createGraphElement(umlChild, parent, location, size);
//		
//		// The ge parent is connected in last because an event may be sent at this moment and trigger a refresh.
//		
//		if(size == null){
//			graphNode.setSize(new Dimension(80, 100));
//		}
//		
//		// all calculus are made in absolute positions
//		Point newpos= new Point(0,0);
//		newpos=LookForElement.calculateAbsolutePosition((GraphNode)parent, location);
//		
////		to say that the artifact belongs to entity parent
//		graphNode.setSemanticParent(parent);
//		
////		 set correct position: calculate position for the artifact
//		graphNode.setPosition(newpos);
//		Point origin=LookForElement.calculateAbsolutePosition(((GraphNode)parent.getContainer()),new Point(0,0));
//		graphNode.setPosition(graphNode.getPosition().getTranslated(origin.getNegated().getCopy()));
//		
//
//		if(parent != null) {
//			parent.getContained().add(graphNode);
//		}
//		return graphNode;
//	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.helper.NodeHelper#createGraphNode(org.eclipse.uml2.uml.Element, com.cea.papyrus.diagraminterchange2.di2.Diagram)
	 */


	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#canExecute(com.cea.papyrus.diagraminterchange2.di2.GraphNode)
	 */
	/**
	 * 
	 * 
	 * @param parent 
	 * 
	 * @return 
	 */
	@Override
	public boolean canCreateGraphElement(GraphElement parent){
		if(parent instanceof Diagram) {
			return true;
		} else if (parent.getSemanticModel()!=null){
			Element parentElt= ((Uml1SemanticModelBridge)parent.getSemanticModel()).getElement();
			if(parentElt!=null){
				return canCreateUMLElement(parentElt);
			}
		}
		return false;
	}

	public Dimension getGraphNodeSize() {
		return new Dimension(80,100);
	}
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#setGraphElementPreferences(com.cea.papyrus.diagraminterchange2.di2.GraphElement)
	 */
	@Override
	public void setGraphElementPreferences(GraphElement graphElement) {	
		// Get the preference store
		IPreferenceStore store = Activator.getDefault().getPreferenceStore();
		
		// Set colors and font
		graphElement.setBackgroundColor(ComponentDiagramPreferenceConstants.getPreferenceArtifactBackgroundColor(store));
		graphElement.setBorderColor(ComponentDiagramPreferenceConstants.getPreferenceArtifactBorderColor(store));
		graphElement.setFontColor(ComponentDiagramPreferenceConstants.getPreferenceArtifactFontColor(store));
		FontData[] fontdata = ComponentDiagramPreferenceConstants.getPreferenceArtifactFont(store);
		if (fontdata.length>0){
			graphElement.setFontFamily(fontdata[0].getName());
			graphElement.setFontSize(fontdata[0].getHeight());
		}
	}
	
}
